package com.groupbuying.settleconsumer.mq;

import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.groupbuying.settleconsumer.constants.RedisKeyEnumConstants;
import com.groupbuying.settleconsumer.service.*;
import com.groupbuying.settleconsumer.utils.JsonUtils;
import com.groupbuying.settleconsumer.utils.RedisUtils;
import com.groupbuying.settleconsumer.utils.apiresult.ApiResult;
import com.groupbuying.settleconsumer.utils.apiresult.ApiResultCode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;



/**
 * MQ消息处理类
 */


@Component
public class SettleMessageListener implements MessageListener {

    public static final Logger logger = LoggerFactory.getLogger(SettleMessageListener.class);

    @Autowired
    private OrderSettlementService orderSettlementService;
    @Autowired
    private SettleUshopYSSplitReceiptService ysSplitReceiptService;
    @Autowired
    private SettleUshopYSWithdrawalReceiptService settleWithdrawalReceiptService;
    @Autowired
    private SettleUshopPaymentReceiptService settlePaymentReceiptService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public Action consume(Message message, ConsumeContext consumeContext) {
        logger.error(new Date() + "MessageListenerImpl Receive message, Topic is:" + message.getTopic()
                + ", MsgId is:" + message.getMsgID()+",tags is:"+message.getTag());
        logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"-----message:"+new String(message.getBody()));
        if (message.getTopic().equals(SettleMQConfig.TOPIC)){
            //获取消息重试次数
            int reconsume = message.getReconsumeTimes();
            if (reconsume == 3) {
                // 消息已经重试了3次，告诉服务器稍后在尝试消费
                logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+" is already try 3 times");
                return Action.CommitMessage;
            }
            if (StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.SETTLE_SPLIT_TAG.equals(message.getTag())){
                logger.error("MessageListenerImpl-->"+SettleMQConfig.SETTLE_SPLIT_TAG);
               // 通知信息流分账
                try{
                    Map body = JsonUtils.jsonToMap(new String(message.getBody()));
                    logger.error("MessageListenerImpl-->body:"+body);
                    String outTradeNo = (String) body.get("outTradeNo");
                    String RedisKey = RedisKeyEnumConstants.ENUM_SETTLE_SPLIT+outTradeNo;
                    //判断MQ是否重复
                    if(redisUtils.isHasKey(RedisKey)){
                        logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"consum already committed");
                        return Action.CommitMessage;
                    }
                    //分账成功后将mq信息存入redis，供mq去重判断使用
                    boolean isTrue = redisUtils.setIfAbsent(RedisKey,body.toString(),180);
                    if(!isTrue){
                        logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"set redisKey fail");
                        return Action.CommitMessage;
                    }
                    ApiResult settleResult = orderSettlementService.createOrederSettle(body);
                    if(ApiResultCode.SUCCESS.code().equals(settleResult.getCode())){
                        logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"consum commit");
                    }
                }catch (Exception e){
                    logger.error("MessageListenerImpl fail: ",e);
                }
                /*解析消息体*/

                return Action.CommitMessage;
            }else if(StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSSPLITRECEIPT_TAG.equals(message.getTag())){
                //银盛异步回执
                logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"银盛异步回执----message:"+new String(message.getBody()));
                if (StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSSPLITRECEIPT_TAG.equals(message.getTag())){
                    /*解析消息体*/
                    String receiptReturn=new String(message.getBody());
                    ApiResult apiResult = ysSplitReceiptService.createAsynchronous(receiptReturn);
                }
            }else if(StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSWITHDRAWALRECEIPT_TAG.equals(message.getTag())){
                //银盛提现异步回执
                logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"银盛提现异步回执---message:"+new String(message.getBody()));
                if (StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSWITHDRAWALRECEIPT_TAG.equals(message.getTag())){
                    /*解析消息体*/
                    String receiptReturn=new String(message.getBody());
                    ApiResult apiResult = settleWithdrawalReceiptService.createWithdrawalReceipt(receiptReturn);
                }
            }else if(StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSSPLIT_TAG.equals(message.getTag())){
                //银盛分账
                if (StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSSPLIT_TAG.equals(message.getTag())){
                    logger.error("MessageListenerImpl()------>调用银盛分账参数，平台内部传的参数Map值为："+new String(message.getBody()));
                    Map body = JsonUtils.jsonToMap(new String(message.getBody()));
                    String outTradeNo = (String) body.get("out_trade_no");
                    //分账成功后将mq信息存入redis，供去重判断使用
                    String splitRedisKey = RedisKeyEnumConstants.ENUM_SETTLE_YSSPLIT+outTradeNo;
                    //判断MQ是否重复
                    if(redisUtils.isHasKey(splitRedisKey)){
                        logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"consum already committed");
                        return Action.CommitMessage;
                    }
                    /*解析消息体*/
                    String receipt=new String(message.getBody());
                    logger.error("MessageListenerImpl()------>解析消息体receipt："+receipt);
                    ApiResult apiResult = ysSplitReceiptService.createSplitReceipt(receipt);
                    logger.error("MessageListenerImpl()------>调用银盛分账返回apiResult："+apiResult);
                    logger.error("MessageListenerImpl()------>调用银盛分账返回apiResult的code："+apiResult.getCode()+"--ApiResultCode.SUCCESS.code()--"+ApiResultCode.SUCCESS.code());
                    if(ApiResultCode.SUCCESS.code().equals(apiResult.getCode())){
                        //分账成功后将mq信息存入redis，供mq去重判断使用
                        redisUtils.setKey(splitRedisKey,body,180);
                        logger.error("MessageListenerImpl()------。存入redis数据："+splitRedisKey);
                        logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"consum commit");
                    }
                }
            }else if(StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSPAYMENT_TAG.equals(message.getTag())){
                //银盛转账/代付异步回执
                if (StringUtils.isNotEmpty(message.getTag()) && SettleMQConfig.YSPAYMENT_TAG.equals(message.getTag())){
                    /*解析消息体*/
                    String paymentReturn=new String(message.getBody());
                    ApiResult apiResult=this.settlePaymentReceiptService.createPaymentReceipt(paymentReturn);
                }
            }
        }
        logger.error("MessageListenerImpl-->consume topic:"+message.getTag()+"，MsgId:"+message.getMsgID()+"consum fail");
        return Action.CommitMessage;
        //如果想测试消息重投的功能,可以将Action.CommitMessage 替换成Action.ReconsumeLater
    }

}
